unit QuickList_DealItem;

interface

uses
  QuickSortList,
  define_dealitem;
  
type       
  PDealItemListItem = ^TDealItemListItem;
  TDealItemListItem = record
    StockPackCode: integer;
    DealItem: PRT_DealItem;
  end;
                        
  TDealItemList = class(TALBaseQuickSortList)
  public
    function  GetItem(Index: Integer): Integer;
    procedure SetItem(Index: Integer; const AStockPackCode: Integer);
    function  GetDealItem(Index: Integer): PRT_DealItem;
    procedure PutDealItem(Index: Integer; ADealItem: PRT_DealItem);
  public
    procedure Notify(Ptr: Pointer; Action: TListNotification); override;
    procedure InsertItem(Index: Integer; const AStockPackCode: integer; ADealItem: PRT_DealItem);
    function  CompareItems(const Index1, Index2: Integer): Integer; override;
  public
    function  IndexOf(AStockPackCode: Integer): Integer;
    function  IndexOfDealItem(ADealItem: PRT_DealItem): Integer;
    Function  AddDealItem(const AStockPackCode: integer; ADealItem: PRT_DealItem): Integer;
    function  Find(AStockPackCode: Integer; var Index: Integer): Boolean;
    procedure InsertObject(Index: Integer; const AStockPackCode: integer; ADealItem: PRT_DealItem);
    //property  Items[Index: Integer]: Integer read GetItem write SetItem; default;
    property  StockPackCode[Index: Integer]: Integer read GetItem write SetItem; default;
    property  DealItem[Index: Integer]: PRT_DealItem read GetDealItem write PutDealItem;
  end;
  
implementation

function TDealItemList.AddDealItem(const AStockPackCode: integer; ADealItem: PRT_DealItem): Integer;
begin
  if not Sorted then
  begin
    Result := FCount
  end else if Find(AStockPackCode, Result) then
  begin
    case Duplicates of
      lstDupIgnore: Exit;
      lstDupError: Error(@SALDuplicateItem, 0);
    end;
  end;
  InsertItem(Result, AStockPackCode, ADealItem);
end;

{*****************************************************************************************}
procedure TDealItemList.InsertItem(Index: Integer; const AStockPackCode: integer; ADealItem: PRT_DealItem);
var
  tmpDealItemListItem: PDealItemListItem;
begin
  New(tmpDealItemListItem);
  tmpDealItemListItem^.StockPackCode := AStockPackCode;
  tmpDealItemListItem^.DealItem := ADealItem;
  try
    inherited InsertItem(index, tmpDealItemListItem);
  except
    Dispose(tmpDealItemListItem);
    raise;
  end;
end;

{***************************************************************************}
function TDealItemList.CompareItems(const Index1, Index2: integer): Integer;
begin
  result := PDealItemListItem(Get(Index1))^.StockPackCode - PDealItemListItem(Get(Index2))^.StockPackCode;
end;

{***********************************************************************}
function TDealItemList.Find(AStockPackCode: Integer; var Index: Integer): Boolean;
var
  L, H, I, C: Integer;
begin
  Result := False;
  L := 0;
  H := FCount - 1;
  while L <= H do
  begin
    I := (L + H) shr 1;
    C := GetItem(I) - AStockPackCode;
    if C < 0 then
    begin
      L := I + 1
    end else
    begin
      H := I - 1;
      if C = 0 then
      begin
        Result := True;
        if Duplicates <> lstDupAccept then
          L := I;
      end;
    end;
  end;
  Index := L;
end;

{*******************************************************}
function TDealItemList.GetItem(Index: Integer): Integer;
begin
  Result := PDealItemListItem(Get(index))^.StockPackCode
end;

{******************************************************}
function TDealItemList.IndexOf(AStockPackCode: Integer): Integer;
begin
  if not Sorted then
  Begin
    Result := 0;
    while (Result < FCount) and (GetItem(result) <> AStockPackCode) do
      Inc(Result);
    if Result = FCount then
      Result := -1;
  end else if not Find(AStockPackCode, Result) then
    Result := -1;
end;
{*******************************************************************************************}
procedure TDealItemList.InsertObject(Index: Integer; const AStockPackCode: integer; ADealItem: PRT_DealItem);
var
  tmpDealItemListItem: PDealItemListItem;
begin
  New(tmpDealItemListItem);
  tmpDealItemListItem^.StockPackCode := AStockPackCode;
  tmpDealItemListItem^.DealItem := ADealItem;
  try
    inherited insert(index, tmpDealItemListItem);
  except
    Dispose(tmpDealItemListItem);
    raise;
  end;
end;

{***********************************************************************}
procedure TDealItemList.Notify(Ptr: Pointer; Action: TListNotification);
begin
  if Action = lstDeleted then
    dispose(ptr);
  inherited Notify(Ptr, Action);
end;

{********************************************************************}
procedure TDealItemList.SetItem(Index: Integer; const AStockPackCode: Integer);
Var
  aPDealItemListItem: PDealItemListItem;
begin
  New(aPDealItemListItem);
  aPDealItemListItem^.StockPackCode := AStockPackCode;
  aPDealItemListItem^.DealItem := nil;
  Try
    Put(Index, aPDealItemListItem);
  except
    Dispose(aPDealItemListItem);
    raise;
  end;
end;

{*********************************************************}
function TDealItemList.GetDealItem(Index: Integer): PRT_DealItem;
begin
  if (Index < 0) or (Index >= FCount) then
    Error(@SALListIndexError, Index);
  Result :=  PDealItemListItem(Get(index))^.DealItem;
end;

{***************************************************************}
function TDealItemList.IndexOfDealItem(ADealItem: PRT_DealItem): Integer;
begin
  for Result := 0 to Count - 1 do
  begin
    if GetDealItem(Result) = ADealItem then
    begin
      Exit;
    end;
  end;
  Result := -1;
end;

{*******************************************************************}
procedure TDealItemList.PutDealItem(Index: Integer; ADealItem: PRT_DealItem);
begin
  if (Index < 0) or (Index >= FCount) then Error(@SALListIndexError, Index);
  PDealItemListItem(Get(index))^.DealItem := ADealItem;
end;

end.
